package com.tzu.utils;

import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.file.Paths;

public class XmlTools {

	/**
	 * 反序列化映射文件到对象 作为泛型参数的类型
	 * 
	 * @param xml
	 *            映射文件路径
	 * @return
	 */
	public static <T> T readXMLByJAXB(Class<T> type, File xml) {
		return JAXB.unmarshal(xml, type);
	}

	/**
	 * 安全模式解析
	 * 
	 * @throws JAXBException
	 * @throws XMLStreamException
	 * @throws FileNotFoundException
	 */
	public static <T> T xmlToObjectBySafe(Class<?> clazz, File xml) throws Exception {
		JAXBContext context = JAXBContext.newInstance(clazz);
		XMLInputFactory xif = XMLInputFactory.newInstance();
		xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
		xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);// 会完全禁止DTD
		XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream(xml));
		Unmarshaller unmarshaller = context.createUnmarshaller();
		return (T) unmarshaller.unmarshal(xsr);
	}

	/** JAXBContext模式解析 */
	public static <T> T xmlToObject(Class<?> clazz, File xml) throws Exception {
		JAXBContext context = JAXBContext.newInstance(clazz);
		Unmarshaller unmarshaller = context.createUnmarshaller();
		return (T) unmarshaller.unmarshal(xml);
	}

	/**
	 * 反序列化映射文件到对象 作为泛型参数的类型
	 * 
	 * @param xml
	 *            映射文件路径
	 * @return
	 */
	public static <T> T readXMLByJAXB(Class<T> type, String xml) {
		return JAXB.unmarshal(xml, type);
	}

	/**
	 * 反序列化映射文件到对象 作为泛型参数的类型
	 * 
	 * @return
	 */
	public static <T> T readXMLByJAXB(Class<T> type, String basepath, String... path) {
		return JAXB.unmarshal(Paths.get(basepath, path).toFile(), type);
	}

}
